/**
 * Copyright (C) 2000, 2001 Maynard Demmon, maynard@organic.com
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or 
 * without modification, are permitted provided that the 
 * following conditions are met:
 * 
 *  - Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 
 *  - Redistributions in binary form must reproduce the above 
 *    copyright notice, this list of conditions and the following 
 *    disclaimer in the documentation and/or other materials provided 
 *    with the distribution. 
 * 
 *  - Neither the names "Java Outline Editor", "JOE" nor the names of its 
 *    contributors may be used to endorse or promote products derived 
 *    from this software without specific prior written permission. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 */
 
package com.organic.maynard.outliner.menus.file;

import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.XMLEncoder;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Logger;

import org.xml.sax.Attributes;

import com.organic.maynard.outliner.Outliner;
import com.organic.maynard.outliner.OutlinerDocument;
import com.organic.maynard.outliner.OutlinerWindowMonitor;
import com.organic.maynard.outliner.dom.Document;
import com.organic.maynard.outliner.guitree.GUITreeComponent;
import com.organic.maynard.outliner.menus.AbstractOutlinerMenuItem;
import com.organic.maynard.outliner.model.DocumentInfo;
import com.organic.maynard.outliner.util.preferences.Preferences;

/**
 * @author  $Author: maynardd $
 * @version $Revision: 1.4 $, $Date: 2004/03/22 04:48:03 $
 */

public class QuitMenuItem extends AbstractOutlinerMenuItem implements ActionListener, GUITreeComponent {
	
	private static final Logger logger = Logger.getLogger("QuitMenuItem");
	private Outliner outliner;
	
	// GUITreeComponent interface
	public void startSetup(Attributes atts) {
		super.startSetup(atts);
		addActionListener(this);
	}
	
	
	// ActionListener Interface
	public void actionPerformed(ActionEvent e) {
		logger.info("Quit Action Listener called");
		if (outliner == null) {
			throw new IllegalStateException("Outliner not present");
		}
		outliner.getModel().savePreferences(outliner);
		quit();
	}
	
	
	// Static Methods
	public void quit() {
		
		// Store List of Open Documents and close documents
		if (!saveOpenDocumentList()) {
			return;
		}
		
		// Store current window position
		Point location = Outliner.outliner.getLocation();
		
		outliner.getModel().setMainWindowXPosition(Double.valueOf(location.getX()).intValue());
		outliner.getModel().setMainWindowYPosition(Double.valueOf(location.getY()).intValue());
		outliner.getModel().savePreferences();
		
		// Hide Desktop
		outliner.setVisible(false);
		//Outliner.outliner.dispose();
		
		// Save config and quit
		Preferences.saveConfigFile(Outliner.CONFIG_FILE);
		RecentFilesList.saveConfigFile(Outliner.RECENT_FILES_FILE);
		
		System.exit(0);
	}
	
	/**
	 * Saves a List of the current open documents to disk so that they can be
	 * re-opened when JOE is relaunched.
	 */
	private static boolean saveOpenDocumentList() {
		// Harvest Data to save and close each document
		ArrayList<DocumentInfo> openFileList = new ArrayList<DocumentInfo>();
		Iterator<Document> it = Outliner.documents.getDefaultOpenDocumentIterator();
		while (it.hasNext()) {
			OutlinerDocument doc = (OutlinerDocument) it.next();
			
			if (OutlinerWindowMonitor.closeInternalFrame(doc)) {
				if (!doc.isModified()) { // Don't store untitled docs that haven't been saved.
					//doc.getDocumentInfo().setProperty(DocumentInfo.KEY_PATH, doc.getDocumentInfo().getFilePath());
					//doc.getDocumentInfo().setProperty(DocumentInfo.KEY_FILE_FORMAT, doc.getDocumentInfo().getFileFormat());
					openFileList.add(doc.getDocumentInfo());
				}
			} else {
				return false;
			}
		}
		
		// Save the file
		/*
		StringBuffer buf = new StringBuffer();
		buf.append(XMLTools.getXMLDeclaration());
		String line_ending = "\n";
		buf.append(line_ending);
		PropertyContainerUtil.writeXML(buf, openFileList, 0, line_ending);
		try {
			FileTools.dumpStringToFile(new File(Outliner.OPEN_FILES_FILE), buf.toString(), "UTF-8");
		} catch (IOException ioe) {
			ioe.printStackTrace();
		}
		*/
		
		try {
			XMLEncoder encoder = new XMLEncoder(new FileOutputStream(Outliner.OPEN_FILES_FILE));
			encoder.writeObject(openFileList);
			encoder.close();
		} catch (IOException ioe) {
			logger.severe("Error writing to file: " + ioe.getMessage());
		}
		
		return true;
	}
	
	public void setOutliner(Outliner anOutliner) {
		outliner = anOutliner;
	}
}